library(dplyr)
library(tidyverse)
library(ggpubr)
hogwarts <- read.csv("hogwarts_2024.csv")
hogwarts |> glimpse()
## Rows: 560
## Columns: 60
## $ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …
## $ house <chr> "Ravenclaw", "Hufflepuff", "Ravencl…
## $ course <int> 4, 5, 4, 2, 2, 6, 7, 5, 2, 3, 7, 5,…
## $ sex <chr> "female", "male", "female", "male",…
## $ wandCore <chr> "unicorn hair", "phoenix feather", …
## $ bloodStatus <chr> "half-blood", "half-blood", "half-b…
## $ result <int> 94, 33, 137, 27, 67, 126, 63, 7, -8…
## $ Defence.against.the.dark.arts.exam <int> 73, 38, 52, 50, 47, 44, 51, 47, 22,…
## $ Flying.exam <int> 33, 36, 73, 42, 41, 52, 34, 34, 23,…
## $ Astronomy.exam <int> 57, 45, 66, 49, 57, 59, 58, 37, 53,…
## $ Herbology.exam <int> 73, 50, 62, 39, 38, 46, 59, 23, 27,…
## $ Divinations.exam <int> 66, 54, 72, 42, 47, 49, 42, 38, 13,…
## $ Charms.exam <int> 60, 70, 77, 46, 35, 55, 86, 20, 40,…
## $ History.of.magic.exam <int> 52, 36, 60, 45, 50, 40, 55, 21, 25,…
## $ Arithmancy.exam <int> 61, 36, 58, 32, 76, 50, 41, 31, 24,…
## $ Care.of.magical.creatures.exam <int> 44, 41, 70, 36, 46, 73, 29, 36, 40,…
## $ Muggle.studies.exam <int> 64, 34, 52, 59, 50, 54, 36, 31, 43,…
## $ Study.of.ancient.runes.exam <int> 50, 35, 59, 39, 48, 56, 47, 41, 34,…
## $ Transfiguration.exam <int> 74, 70, 70, 15, 32, 86, 100, 31, 23…
## $ Potions.exam <int> 67, 38, 22, 64, 56, 60, 62, 55, 15,…
## $ week_1 <int> 0, -5, 0, -1, 1, 5, 1, -20, 3, -20,…
## $ week_2 <int> -10, 1, 0, 5, 20, 10, -5, 10, 1, 10…
## $ week_3 <int> 0, -1, 1, -5, 10, -5, 3, -5, -3, 5,…
## $ week_4 <int> 10, 1, -1, 10, -10, 10, 0, -10, -1,…
## $ week_5 <int> 3, -5, 3, 0, -1, 20, 5, 5, -3, 5, 5…
## $ week_6 <int> -20, 20, 0, 0, 0, 0, 0, 5, 0, -1, 1…
## $ week_7 <int> 10, 10, 1, -3, -20, 1, 10, 3, -5, 1…
## $ week_8 <int> 5, 5, 1, -5, 5, 5, 0, 1, 0, 20, -20…
## $ week_9 <int> 1, 1, 3, -1, 0, 3, -20, -20, -10, 5…
## $ week_10 <int> 20, -10, 1, 5, -1, 0, 5, -5, 5, 3, …
## $ week_11 <int> 5, -10, 20, 0, 0, 0, 5, 10, 5, 5, 1…
## $ week_12 <int> 5, -5, 1, -20, -10, -5, 0, 5, 1, 5,…
## $ week_13 <int> -20, -5, 10, 0, 0, 1, -1, 10, -20, …
## $ week_14 <int> 0, 5, 3, 10, -10, 20, 0, -20, -20, …
## $ week_15 <int> 1, 20, 1, 0, -20, 10, 1, 3, -20, 5,…
## $ week_16 <int> 20, 5, 5, 5, 0, 3, 10, -1, 5, 5, -1…
## $ week_17 <int> 3, 0, 10, 5, 5, -5, -1, 10, -10, 0,…
## $ week_18 <int> 10, 5, 5, 5, 10, -20, 0, 10, 3, 5, …
## $ week_19 <int> -10, 0, -5, -1, 0, -1, 0, 20, 0, -3…
## $ week_20 <int> 10, -10, 5, 10, 0, -1, -1, 10, 0, 0…
## $ week_21 <int> 0, 5, 5, 3, 5, 0, 0, -5, -5, 5, 5, …
## $ week_22 <int> 20, -5, 5, 0, 20, 5, -1, 0, 0, 20, …
## $ week_23 <int> 5, 1, -3, 20, -5, 20, 0, 1, 1, 5, -…
## $ week_24 <int> 10, -20, -20, 0, 10, 5, 5, -3, -5, …
## $ week_25 <int> 0, -20, 1, 3, 5, 1, -5, 0, -20, 20,…
## $ week_26 <int> 10, 10, 5, -1, 0, 5, 5, -3, 0, 20, …
## $ week_27 <int> 5, 5, -3, 0, 20, 5, 0, -5, 10, 3, -…
## $ week_28 <int> -3, 20, 20, 1, 10, 5, 1, 10, 0, 1, …
## $ week_29 <int> -20, -5, 5, 5, -10, 1, 0, -3, 0, 1,…
## $ week_30 <int> 5, 1, -5, 5, -5, -1, -20, 20, 1, 3,…
## $ week_31 <int> 5, 5, 20, -5, -10, -3, 0, -10, 20, …
## $ week_32 <int> -5, 1, 20, -1, -10, 5, 10, 1, 0, 0,…
## $ week_33 <int> 0, 10, 3, 3, 0, 0, -1, 0, -20, 3, 1…
## $ week_34 <int> 0, -1, 0, 0, 10, 3, 20, -5, 10, 3, …
## $ week_35 <int> 5, -5, 3, -10, 3, -5, 0, 0, 0, 0, 0…
## $ week_36 <int> 1, 5, 1, -20, 5, 20, -1, -3, 1, 3, …
## $ week_37 <int> 0, 0, 10, -1, 10, 3, 3, 0, 20, 1, 1…
## $ week_38 <int> 10, -1, 0, -5, 5, 5, 20, -5, -3, 0,…
## $ week_39 <int> 3, 5, 1, 10, 20, 0, 5, 1, -5, 0, 5,…
## $ week_40 <int> 0, 0, 5, 1, 5, 1, 10, -5, -20, 3, -…
# Changing some variables type to factors
hogwarts <- hogwarts |> mutate(
across(c(house, course, sex, wandCore, bloodStatus), ~ as.factor(.x))
)
theme_custom <- theme(
panel.background = element_rect(fill = "white", colour = "black"),
panel.grid.major = element_line(colour = "grey90", size = 0.8),
plot.title = element_text(size = 30, hjust = 0.5),
plot.subtitle = element_text(size = 25, hjust = 0.5),
strip.text = element_text(size = 20),
axis.text = element_text(size = 20),
axis.title = element_text(size = 25),
legend.title = element_text(size = 25),
legend.text = element_text(size = 20)
)
herbology.score <- hogwarts %>%
ggplot(aes(x = `result`,
y = `Herbology.exam`))+
geom_point()+
geom_smooth(se = FALSE,
method = "lm",
colour = "goldenrod1")+
theme_custom
herbology.score
График показывает положительную корреляцию между переменными суммарный балл студента за год и оценка экзамена по травологии: чем выше значение балла за год, тем выше результат на экзамене. Оранжевая линия тренда подтверждает эту связь, но разброс точек вокруг линии указывает на наличие шума и выбросов в данных.
exams.score <- hogwarts %>%
pivot_longer(cols = c(Herbology.exam, Muggle.studies.exam, Divinations.exam, Potions.exam),
names_to = "subject",
values_to = "exam.score") %>%
#select(id, house, subject, exam.score) %>%
ggplot(aes(x = `result`,
y = `exam.score`,
colour = `house`))+
scale_colour_manual(values = c("Gryffindor" = "#C50000",
"Hufflepuff" = "#ECB939",
"Ravenclaw" = "#41A6D9",
"Slytherin" = "#1F5D25"))+
geom_point()+
geom_smooth(se = FALSE,
method = "lm")+
facet_wrap(~ subject)+
theme_custom
exams.score
Интерпретация: по экзаменам прорицания, гербология и маггловедению надблюдается примерно одинаковая картина - тренды оценок студентов разных факультетов похожи (наблюдается положительная корреляция между суммарным баллом студента и оценкой за экзамен), однако у студентов факультета Слизерин наблюдается большее число студентов с общим баллом меньше чем -100, и соответствующей низкой оценкой за экзаемн. По экзамену зельеварение студенты Слизерина стабильно получают высокий балл (почти все получили балл больше 75), независимо от суммарного балла (и можно наблюдать две группы студентов: высокий суммарный балл - высокая оценка за экзамен, низкий суммарный балл - высокая оценка за экзамен). Студенты остальных факультетов получают значительно более низкую оценку за экзамен по зельеварению, и можно наблюдать слабую отрицательную корреляцию между суммарным баллом и оценкой за экзамен. Можно даже сказать что студенты Грифииндора, Хаффлпаффа и Рэйвенкло получают стабильно средне-низкие (не выше 75 баллов) оценки за экзамен по зельеварению.
exams.score.slytherin <- hogwarts %>%
pivot_longer(cols = c(Herbology.exam, Muggle.studies.exam, Divinations.exam, Potions.exam),
names_to = "subject",
values_to = "exam.score") %>%
select(id, house, subject, exam.score, result) %>%
ggplot(aes(x = `result`,
y = `exam.score`,
colour = `house`,
linetype = ifelse(house == "Slytherin", "Slytherin", "Other Houses")))+
scale_colour_manual(values = c("Gryffindor" = "#C50000",
"Hufflepuff" = "#ECB939",
"Ravenclaw" = "#41A6D9",
"Slytherin" = "#1F5D25"),
name ="House")+
#scale_linetype_manual(name = "Trend Line Type")+
labs(linetype = "Trend Line Type")+
geom_point()+
geom_smooth(se = FALSE,
method = "lm",
aes(group = ifelse(house == "Slytherin", house, "Other Houses")))+
facet_wrap(~ subject)+
theme_custom
exams.score.slytherin
## geom_col ### 1
col1 <- hogwarts %>%
select(id, bloodStatus, week_1:week_17) %>%
rowwise %>%
mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
group_by(bloodStatus)
ggplot(col1)+
geom_col(aes(x = bloodStatus,
y = sum(total.score),
fill = bloodStatus))+
theme_custom
col1
## # A tibble: 560 × 20
## # Groups: bloodStatus [3]
## id bloodStatus week_1 week_2 week_3 week_4 week_5 week_6 week_7 week_8
## <int> <fct> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 1 half-blood 0 -10 0 10 3 -20 10 5
## 2 2 half-blood -5 1 -1 1 -5 20 10 5
## 3 3 half-blood 0 0 1 -1 3 0 1 1
## 4 4 half-blood -1 5 -5 10 0 0 -3 -5
## 5 5 half-blood 1 20 10 -10 -1 0 -20 5
## 6 6 muggle-born 5 10 -5 10 20 0 1 5
## 7 7 half-blood 1 -5 3 0 5 0 10 0
## 8 8 half-blood -20 10 -5 -10 5 5 3 1
## 9 9 half-blood 3 1 -3 -1 -3 0 -5 0
## 10 10 pure-blood -20 10 5 1 5 -1 10 20
## # ℹ 550 more rows
## # ℹ 10 more variables: week_9 <int>, week_10 <int>, week_11 <int>,
## # week_12 <int>, week_13 <int>, week_14 <int>, week_15 <int>, week_16 <int>,
## # week_17 <int>, total.score <int>
Гипотеза: магглорожденных студентов сравнительно мало и им явно приходится сложно и трудно в первом семестре, этим можно объяснить их низкий балл. А различия в балле полукровок и чистокровных также можно объяснить количеством студентов (полукровок намного больше, чем чистокровных).
blood.status.result <- hogwarts %>%
rowwise() %>%
mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
group_by(bloodStatus) %>%
summarise(blood.st.total.score = sum(total.score),
num_students = n())
#col2 <- hogwarts %>%
#select(id, bloodStatus, week_1:week_17) %>%
#rowwise() %>%
#mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
#group_by(bloodStatus)
ggplot(blood.status.result, aes(x = fct_reorder(bloodStatus, blood.st.total.score, .desc = TRUE),
y = blood.st.total.score,
fill = bloodStatus))+
geom_col()+
geom_label(aes(label = num_students), size = 7)+
labs(x = "blood status",
y = "total score")+
theme_custom
Интерпретация: из графика видно, что студентов-полукровок больше, чем остальных студентов, а число чистокровных студентов больше чем число магглорожденных студентов. Соответственно и баллов было заработано пропорциональное количество. Гипотеза соотносится с гипотезой из пункта 1.
blood.status.result <- hogwarts %>%
rowwise() %>%
mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
group_by(bloodStatus, sex) %>%
summarise(blood.st.total.score = sum(total.score),
num_students = n()) %>%
mutate(blood.st.sex = paste0(bloodStatus, " ", sex))
ggplot(blood.status.result,
aes(y = fct_reorder(blood.st.sex, blood.st.total.score, .desc = FALSE),
x = blood.st.total.score,))+
geom_col(aes(fill = bloodStatus))+
#theme(axis.text.x = element_text(angle = 20))+
geom_label(aes(label = num_students,
x = 9000), size = 7)+
labs(y = "blood status",
x = "score",
title = "distribution of student scores for 1 semester depending on gender and blood status")+
scale_x_continuous(breaks = seq(0, 10000, 1000))+ #labels = paste0(seq(0, 10000, 1000), " p."))+
theme_custom
#ggsave("blood.status_and_sex_result_plot.png", blood.status.result, width = 20, height = 16, units = "in", dpi = 300)
Комментарий к графику: в задании сказано расположить в порядке убывания, вроде так и расположила(сверху вниз убывает, но в аргументе .desc = FALSE) Также в задании не указано, какую информацию должны содержать текстовые метки в этом задании - оставила как в предыдущем, количество студентов в коле.
coord_flip()
Эта функция разворачивает графики, меняет местами оси x и y. Думаю, эта функция бывает полезна, когда внутри ggplot и geom_ лежит много аргументов, и сложно будет вручную менять оси местами. Или когда строим несколько графиков, и аргументы заложены внутри ggplot, и чтобы не менять их местами можно использовать coord_flip, это будет быстрее и удобнее (и отменять эту функцию тоже удобнее, чем обратно вручную менять оси местами) Плюсы: быстрее и удобнее поменять оси местами, не изменяя код; работает со многими функциями внутри ggplot Минусы: не позволяет вручную настраивать, что именно отобразится на оси, не гибка; может напортачить со сложными графиками
potion_vs_runes <- hogwarts %>%
mutate(id = as.factor(id)) %>%
pivot_longer(cols = c(Potions.exam, Study.of.ancient.runes.exam),
names_to = "subject",
values_to = "exam.score") %>%
select(id, subject, exam.score, house, sex, course)
plot3.1.1 <- ggplot(potion_vs_runes)+
geom_density(aes(x = exam.score, fill = subject),
alpha = 0.5
)+
#facet_grid(.~sex)+
labs(x = "exam score")+
theme(legend.position = "none")+
theme_custom
plot3.1.2 <- ggplot(potion_vs_runes)+
geom_histogram(aes(x = exam.score, fill = subject),
colour = "black",
bins = 20,
alpha = 0.5,
position = "identity"
)+
labs(x = "exam score")+
theme(legend.position = "none")+
theme_custom
plot3.1.3 <- ggplot(potion_vs_runes)+
geom_boxplot(aes(x = fct_reorder(house, exam.score, .desc = TRUE),
y = exam.score,
fill = subject),
width = 0.5,
size = 1.2)+
labs(x = "exam score")+
theme(legend.position = "none")+
theme_custom
#ggarrange(plotlist = list(plot3.1.1, plot3.1.2, plot3.1.3, plot3.1.3), ncol = 2, nrow = 2)
comb.plot <- ggarrange(
ggarrange(plot3.1.1, plot3.1.2, ncol = 2), # Верхняя строка: два графика
plot3.1.3, # Нижняя строка: один график
ncol = 1, # Внешняя структура в один столбец
heights = c(1, 1.5),
common.legend = TRUE, # Одна общая легенда
legend = "bottom" # Легенда снизу
)
annotate_figure(comb.plot, top = text_grob("Comparison of Potion exam score and Study of ancient runes exam score",
size = 26,
face = "bold"))
#title = "Comparison of Potion exam score and Study of ancient runes exam score",
blood.and.potion <- hogwarts %>%
group_by(bloodStatus) %>%
summarise(meanPotionScore = mean(Potions.exam) %>% round(2),
Min = (min(Potions.exam) %>% round(2)),
Max = (max(Potions.exam) %>% round(2))
)
ggplot(blood.and.potion)+
#geom_col(aes(x = bloodStatus,
#y = meanPotionScore,
#fill = bloodStatus))+
geom_pointrange(aes(x = bloodStatus,
y = meanPotionScore,
ymin = Min,
ymax = Max,
colour = bloodStatus),
linewidth =2,
fatten = 10)+
labs(title = "Distribution of average potions exam scores among students with different blood
status",
y = "Potiom exam score",
caption = "dots - average score, lines - min-max")+
theme(legend.position = "none",
plot.caption = element_text(size = 22, hjust = 1))+
#ggplot(aes(x = fct_reorder(bloodStatus, Potions.exam, .desc = TRUE),
#y = Potions.exam))+
#geom_boxplot(aes(fill = bloodStatus),
#notch = TRUE)+
theme_custom
blood.and.potion
## # A tibble: 3 × 4
## bloodStatus meanPotionScore Min Max
## <fct> <dbl> <dbl> <dbl>
## 1 half-blood 47.1 0 100
## 2 muggle-born 37.4 1 100
## 3 pure-blood 50.0 0 100
blood.potions <- hogwarts %>%
group_by(house, bloodStatus) %>%
summarize(mean.Potions.exam = mean(Potions.exam, na.rm = TRUE) %>% round(2)
#Min = (min(Potions.exam) %>% round(2)),
#Max = (max(Potions.exam) %>% round(2))
)
ggplot(blood.potions)+
#geom_col(aes(x = bloodStatus,
#y = meanPotionScore,
#fill = bloodStatus))+
geom_point(aes(x = bloodStatus,
y = mean.Potions.exam,
colour = house),
size =8)+
scale_colour_manual(values = c("Gryffindor" = "#C50000",
"Hufflepuff" = "#ECB939",
"Ravenclaw" = "#41A6D9",
"Slytherin" = "#1F5D25"),
name ="House")+
theme_custom
blood.potions
## # A tibble: 12 × 3
## # Groups: house [4]
## house bloodStatus mean.Potions.exam
## <fct> <fct> <dbl>
## 1 Gryffindor half-blood 33.7
## 2 Gryffindor muggle-born 25.6
## 3 Gryffindor pure-blood 37.8
## 4 Hufflepuff half-blood 35.3
## 5 Hufflepuff muggle-born 34.8
## 6 Hufflepuff pure-blood 37.4
## 7 Ravenclaw half-blood 34.5
## 8 Ravenclaw muggle-born 30.1
## 9 Ravenclaw pure-blood 43.7
## 10 Slytherin half-blood 84.4
## 11 Slytherin muggle-born 85
## 12 Slytherin pure-blood 82.8
#ggarrange()
Комментарий: объединить последние два графика
potion_vs_runes <- hogwarts %>%
#summarise(meanPotion = mean(`Potion.exam`), meanRunes = mean(`Study.of.ancient.runes.exam
#`)) %>%
pivot_longer(cols = c(Potions.exam, Study.of.ancient.runes.exam),
names_to = "subject",
values_to = "exam.score") %>%
select(id, subject, exam.score, house)
test_col <- ggplot(potion_vs_runes, aes(x = subject, y = exam.score))+
geom_col(aes(fill = house))+
theme_custom
test_col
#test_pie <- ggplot(potion_vs_runes)+
#geom_col(aes(x = '', y = exam.score, fill = subject))+
#coord_polar(theta = "y")+
#scale_fill_manual(values = c("Gryffindor" = "#C50000",
# "Hufflepuff" = "#ECB939",
# "Ravenclaw" = "#41A6D9",
# "Slytherin" = "#1F5D25"),
# name ="House")+
#theme_custom
#test_pie
#ggarrange(plotlist = list(test_pie, test_col), ncol = 2)